package org.takeback.chat.store.room;

import org.takeback.chat.service.*;
import org.springframework.beans.factory.annotation.*;
import com.google.common.cache.*;
import org.takeback.chat.entity.*;
import java.io.*;
import org.takeback.util.exception.*;
import org.takeback.util.*;
import java.util.*;
import org.takeback.chat.store.user.*;
import com.google.common.collect.*;
import org.apache.commons.lang3.*;
import org.takeback.chat.store.*;

public class DefaultRoomStore implements RoomStore {
	@Autowired
	private RoomService roomService;
	private LoadingCache<String, Room> roomPojoMap;
	private int pageSize;

	public DefaultRoomStore() {
		this.pageSize = 5;
	}

	public void init() {
		this.roomPojoMap = (LoadingCache<String, Room>) CacheBuilder.newBuilder()
				.build((CacheLoader) new CacheLoader<String, Room>() {
            public Room load(final String s) throws Exception {
                final GcRoom gcRoom = DefaultRoomStore.this.roomService.get(GcRoom.class, s);
                if (gcRoom == null) {
                    throw new CodedBaseException(530, "room " + s + " not exists");
                }
                final Room room = BeanUtils.map(gcRoom, Room.class);
                final Map<String, Object> props = DefaultRoomStore.this.roomService.getRoomProperties(gcRoom.getId());
                room.getProperties().putAll(props);
                return room;
            }
				});
		final List<GcRoom> list = (List<GcRoom>) this.roomService.getActivedRooms();
		if (list != null && !list.isEmpty()) {
			for (final GcRoom gcRoom : list) {
                final Room room = BeanUtils.map(gcRoom, Room.class);
                final Map<String, Object> props = this.roomService.getRoomProperties(gcRoom.getId());
                room.getProperties().putAll(props);
				this.roomPojoMap.put((String) room.getId(), room);
			}
		}
	}

	public Room get(final Serializable roomId) {
		try {
			return (Room) this.roomPojoMap.get((String) roomId);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public void reload(final Serializable roomId) {
		Room room = this.get(roomId);
		final GcRoom gcRoom = (GcRoom) this.roomService.get((Class) GcRoom.class, roomId);
		if (gcRoom == null) {
			return;
		}
		if (room == null) {
			room = (Room) BeanUtils.map((Object) gcRoom, (Class) Room.class);
			this.roomPojoMap.put((String) room.getId(), room);
		} else {
			BeanUtils.copy((Object) gcRoom, (Object) room);
		}
		final Map<String, Object> props = (Map<String, Object>) this.roomService.getRoomProperties(gcRoom.getId());
		room.getProperties().putAll(props);
	}

	@Override
	public void fireUserLeft(final User user) {
		final Map<String, Room> rooms = (Map<String, Room>) this.roomPojoMap.asMap();
		if (rooms != null && !rooms.isEmpty()) {
			for (final Room room : rooms.values()) {
				room.left(user);
			}
		}
	}

	@Override
	public List<Room> getByType(final String type) {
		final List<Room> ls = Lists.newArrayList();
		for (final String s : this.roomPojoMap.asMap().keySet()) {
			final Room room = this.get(s);
			if (room.getType().equals(type)) {
				ls.add(room);
			}
		}
		return ls;
	}

	@Override
	public List<Room> getByCatalog(final String catalog) {
		final List<Room> ls = Lists.newArrayList();
		for (final String s : this.roomPojoMap.asMap().keySet()) {
			final Room room = this.get(s);
			if (StringUtils.isEmpty((CharSequence) catalog)) {
				ls.add(room);
			} else {
				if (!catalog.equals(room.getCatalog())) {
					continue;
				}
				ls.add(room);
			}
		}
		return ls;
	}

	@Override
	public List<Room> getByCatalog(final String catalog, final int pageNo) {
		final List<Room> rooms = this.getByCatalog(catalog);
		if (rooms == null) {
			return null;
		}
		final int start = this.pageSize * (pageNo - 1);
		if (start > rooms.size() - 1) {
			return null;
		}
		if (start + this.pageSize > rooms.size() - 1) {
			return rooms.subList(start, rooms.size() - 1);
		}
		return rooms.subList(start, start + this.pageSize);
	}

	@Override
	public List<Room> query(final String condition) {
		return null;
	}

	public int getPageSize() {
		return this.pageSize;
	}

	public void setPageSize(final int pageSize) {
		this.pageSize = pageSize;
	}

	@Override
	public void delete(final String roomId) {
		this.roomPojoMap.invalidate((Object) roomId);
	}
}
